package demo.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import demo.Result;
import demo.dto.RequestModifyUserDto;
import demo.dto.ResponseEmployeeDataDto;
import demo.dto.ResponseUserDataDto;
import demo.entity.Company;
import demo.entity.Department;
import demo.entity.User;
import demo.entity.UserCompany;
import demo.service.CompanyService;
import demo.service.DepartmentService;
import demo.service.UserCompanyService;
import demo.service.UserService;
import demo.util.CardIdUtil;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 用户信息 Controller
 *
 * @author 肖溥博文
 * @version 1.5
 */
@RestController
public class UserController {

    @Autowired
    UserService userService;

    @Autowired
    UserCompanyService userCompanyService;

    @Autowired
    DepartmentService departmentService;

    @Autowired
    CompanyService companyService;

    /**
     * 获取公司所有用户的数据
     *
     * @param company 公司对象
     * @return 公司所有用户数据（以结果对象形式）
     */
    @PostMapping("/getEmployeesData")
    @RequiresAuthentication
    public Result getEmployeesData(@RequestBody Company company) {
        Long companyId = company.getCompanyId();
        List<UserCompany> userCompanyList = userCompanyService.listUserCompanies(companyId);
        List<Department> departmentList = (List<Department>) departmentService.listDepartments(companyId).getData();

        Map<Long, Department> departmentMap = new HashMap<>();
        for (Department department : departmentList) {
            departmentMap.put(department.getDepartmentId(), department);
        }

        List<ResponseEmployeeDataDto> responseEmployeeDataDtos = new ArrayList<>();

        for (UserCompany userCompany : userCompanyList) {
            ResponseEmployeeDataDto responseEmployeeDataDto = new ResponseEmployeeDataDto();
            User user = userService.findUserByUid(userCompany.getUid());
            user.setPassword("");
            user.setCardId(CardIdUtil.anonymize(user.getCardId()));
            responseEmployeeDataDto.setUser(user);
            responseEmployeeDataDto.setUserCompany(userCompany);
            responseEmployeeDataDto.setDepartment(departmentMap.get(userCompany.getDepartmentId()));
            responseEmployeeDataDtos.add(responseEmployeeDataDto);
        }

        // ATTENTION:
        // You can put List object directly into Result.success()
        // and it will be automatically transformed into a array in a json.
        return Result.success("查询成功", responseEmployeeDataDtos);
    }

    /**
     * 获取单个职工的信息
     *
     * @param user 用户对象，必须包含一个用户 id
     * @return 一个 responseEmployeeDataDto json，包含其所有个人信息、所在部门、职位
     */
    @PostMapping("/getEmployeeData")
    @RequiresAuthentication
    public Result getEmployeeData(@RequestBody User user) {
        User userFound = userService.findUserByUid(user.getUid());
        if (userFound == null) {
            return Result.error("用户不存在");
        }

        ResponseEmployeeDataDto responseEmployeeDataDto = new ResponseEmployeeDataDto();
        userFound.setPassword("");
        userFound.setCardId(CardIdUtil.anonymize(userFound.getCardId()));
        responseEmployeeDataDto.setUser(userFound);

        Result resultUserCompany = userCompanyService.findLatestUserCompanyByUid(user.getUid());
        if (resultUserCompany.getCode() == 200) {
            UserCompany userCompany = (UserCompany) resultUserCompany.getData();
            Department department = departmentService.findByDepartmentId(userCompany.getDepartmentId());
            responseEmployeeDataDto.setUserCompany(userCompany);
            responseEmployeeDataDto.setDepartment(department);
        }

        return Result.success("查询成功", responseEmployeeDataDto);
    }


    /**
     * 按传入的 uid 获取用户数据
     *
     * @param user 必须包含一个用户 uid
     * @return 结果对象，包含用户的基本信息
     */
    @PostMapping("/getUserData")
    @RequiresAuthentication
    public Result getUserData(@RequestBody User user) {
        User userFound = userService.findUserByUid(user.getUid());
        if (userFound == null) {
            return Result.error("用户不存在");
        }

        ResponseUserDataDto responseUserDataDto = new ResponseUserDataDto();
        BeanUtil.copyProperties(userFound, responseUserDataDto);

        Result resultUserCompany = userCompanyService.findLatestUserCompanyByUid(user.getUid());
        if (resultUserCompany.getCode() == 200) {
            UserCompany userCompany = (UserCompany) resultUserCompany.getData();
            Company company = (Company) companyService.find(userCompany.getCompanyId()).getData();
            Department department = departmentService.findByDepartmentId(userCompany.getDepartmentId());
            responseUserDataDto.setPosition(userCompany.getPosition());
            responseUserDataDto.setCompany(company);
            responseUserDataDto.setDepartment(department);
        }

        return Result.success("用户信息查询成功", responseUserDataDto);
    }

    /**
     * 获取所有用户的基本信息
     *
     * @return 结果对象，包含所有用户的基本信息
     */
    @PostMapping("/getUsersData")
    @RequiresAuthentication
    public Result getUsersData() {
        List<User> userList = userService.listUsers();
        List<Company> companyList = companyService.listCompanies();
        List<UserCompany> userCompanyList = userCompanyService.listLatestUserCompanies();
        List<Department> departmentList = departmentService.listDepartments();

        Map<Long, Company> companyMap = new HashMap<>();
        Map<Long, UserCompany> userCompanyMap = new HashMap<>();
        Map<Long, Department> departmentMap = new HashMap<>();

        List<ResponseUserDataDto> responseUserDataDtoList = new ArrayList<>();

        for (Company company : companyList) {
            companyMap.put(company.getCompanyId(), company);
        }

        for (UserCompany userCompany : userCompanyList) {
            userCompanyMap.put(userCompany.getUid(), userCompany);
        }

        for (Department department : departmentList) {
            departmentMap.put(department.getDepartmentId(), department);
        }

        for (User user : userList) {
            ResponseUserDataDto responseUserDataDto = new ResponseUserDataDto();
            BeanUtil.copyProperties(user, responseUserDataDto);
            UserCompany userCompany = userCompanyMap.get(user.getUid());
            if (userCompany != null) {
                responseUserDataDto.setPosition(userCompany.getPosition());
                responseUserDataDto.setCompany(companyMap.get(userCompany.getCompanyId()));
                responseUserDataDto.setDepartment(departmentMap.get(userCompany.getDepartmentId()));
            }
            responseUserDataDtoList.add(responseUserDataDto);
        }

        return Result.success("查询成功", responseUserDataDtoList);
    }

    /**
     * 修改用户基本信息
     *
     * @param requestModifyUserDto 必须包含用户的 uid
     * @return 结果对象
     */
    @PostMapping("/modifyUserData")
    @RequiresAuthentication
    public Result modifyUserData(@Validated @RequestBody RequestModifyUserDto requestModifyUserDto) {
        Long uid = requestModifyUserDto.getUid();
        User storedUser = userService.findUserByUid(uid);
        if (storedUser == null) {
            return Result.error("用户信息修改失败，不存在该用户");
        }

        BeanUtil.copyProperties(requestModifyUserDto, storedUser);

        return userService.modifyUser(storedUser);
    }
}
